/*
 * Systemprogrammierung
 * Multiplayer-Quiz
 *
 * Client
 *
 * gui_thread.c: Implementierung des GUI-Threads
 */

#include "gui/gui_interface.h"
#include "common/sockets.h"
#include "gui_thread.h"
#include "main.h"

static int sock;

static int client_id;

/* Antwort Index
 * 0-3 */
static uint8_t answer;

/* Setzt den Antwort Index */
void set_answer(int index)
{
	answer = (uint8_t) index;
}

/* Liefert Antwort Index */
int get_answer() { return answer; }


/* Aufruf, falls neuer Katalog ausgewählt wurde
 * Sendet CATALOG_CHANGE an den Sever */
void preparation_onCatalogChanged(const char *newSelection)
{
	debugPrint("Katalogauswahl: %s", newSelection);

	// Neuen Katalog an Server senden
	if (catch_com_err(send_MSG(sock, CATALOG_CHANGE, strlen(newSelection),
			(void*) newSelection)) == COM_ERR)
	{
		debugPrint("Verbindung zum Server verloren\n");
		guiShowErrorDialog("Verbindung zum Server verloren", 1);
	}
}

/* Aufruf, falls Startbutton geklickt wurde
 * Sendet START_GAME an den Server */
void preparation_onStartClicked(const char *currentSelection)
{
	debugPrint("Starte Katalog %s", currentSelection);

	// "Start" an Server senden
	if (catch_com_err(send_MSG(sock, START_GAME, strlen(currentSelection),
			(void*) currentSelection)) == COM_ERR)
	{
		debugPrint("Verbindung zum Server verloren\n");
		guiShowErrorDialog("Verbindung zum Server verloren", 1);
	}
}

/* Aufruf, falls Vorbereitungsfenster geschlossen wurde */
void preparation_onWindowClosed(void)
{
	debugPrint("Vorbereitungsfenster geschlossen");
	close(sock);
	guiQuit();
}

/* Aufruf, falls Antwort geklickt wurde
 * Setzt Antwort Index und schickt Antwort an Server*/
void game_onAnswerClicked(int index)
{
	debugPrint("Antwort %i ausgewählt", index);
	set_answer(index);
	game_setAnswerButtonsEnabled(0);

	// Antwort an Server senden
	if (catch_com_err(
			send_MSG(sock, QUESTION_ANSWERED, sizeof(answer), &answer))
			== COM_ERR)
	{
		debugPrint("Verbindung zum Server verloren\n");
		guiShowErrorDialog("Verbindung zum Server verloren", 1);
	}
}

/* Aufruf, falls Spielfenster geschlossen wurde */
void game_onWindowClosed(void)
{
	debugPrint("Spielfenster geschlossen");
	close(sock);
	guiQuit();
}

/* Startfunktion des GUI Threads */
void* gui_thread(void* param)
{

	// Hole Socket von Server
	sock = get_socket();

	int argc = get_main_argc();

	char **argv = get_main_argv();

	// GUI initialisieren
	guiInit(&argc, &argv);

	// Semaphor hochzählen, damit Listener Thread fortfahren kann (GUI wurde initialisiert)
	sem_post(&gui_thread_init);

	client_id = get_client_id();

	// Wenn Client-ID = 0 wird Client Spielleiter
	if (client_id == 0)
	{
		// Schalte Spielleiter-Rechte frei
		preparation_setMode(PREPARATION_MODE_PRIVILEGED);

		debugPrint("Login erfolgreich - Spielleiter - Client ID: %d\n",
				client_id);

	} else {

		// Client ist normaler Spieler
		preparation_setMode(PREPARATION_MODE_NORMAL);

		debugPrint("Login erfolgreich - Client ID: %d\n", client_id);
	}

	/* Anfragen der Katalogliste von Server */
	if (catch_com_err(send_MSG(sock, CATALOG_REQUEST, 0, NULL)) == COM_ERR)
	{
		debugPrint("Verbindung zum Server verloren\n");

		// Thread beenden
		pthread_exit(NULL);

		return NULL;
	}

	// Zeige Fenster der Spielvorbereitung an
	preparation_showWindow();

	/* GUI-Schleife (Thread steht, bis guiQuit aufgerufen wird) */
	guiMain();

	// GUI freigeben
	guiDestroy();

	// Thread beenden
	pthread_exit(NULL);

	return NULL;
}
